package s;
import java.math.BigInteger;
import java.util.Scanner;
public class RSA {
	private long p,q,phi,e,d,n;

	public RSA(){
		Scanner input = new Scanner(System.in);
		System.out.println("请输入第一个素数p:");
		 p = input.nextLong();
		System.out.println("请输入第二个素数q:");
		 q = input.nextLong();
		// 求出n的值
		 n = p*q;
		// 求出phi的值
		 phi = (p-1)*(q-1);
		//判断e和phi是否互素
				while(gcd(e,phi)!=1){
				
			       e = (long)(Math.random()*phi)+1;
				}
		System.out.println("e:"+e);
		//调用calculateD()方法，获得d值
		 d = calculateD(p,q);
		 System.out.println("d:"+d);
		  }
	public long getP(){
		return p;
	}

	public long  getQ(){
		return q;
	}
  //此方法得到d值
	private long calculateD(long p,long q){
		
		long t0 = 0,t1 = 1,t2 = -1;
	    long r0 = (p-1)*(q-1), m = r0,r1 = e,r2 = -1;
	    do{
	    	 q = r0/r1;
	    	r2 = r0-r1*q;
	    	if(r2==0)break;
	    	t2 = t0-t1*q;
	    	while(t2<0){
	    		t2+=m;
	    	}
	    	if(t2>=m){
	    		t2%=m;
	    	}
	    	r0=r1;
	    	r1=r2;
	    	t0=t1;
	    	t1=t2;
	    }while(r2!=0);
	    if(r1!=1){
	    	return 0;
	    }
	    else{
	    	return t2;
	    }
	}
	
	 //判断求出a和b的最大公因数 
	public long gcd(long a,long b){
		while(b!=0){
			long temp = a%b;
			a = b;
			b = temp;
			
		}
		return a;
	}
	  
	//加密方法
	public BigInteger encode(BigInteger data){
		return pow(data,e).mod(new BigInteger(n+""));
		
	}
	
	//解密方法
	public BigInteger decode(BigInteger code){
		return pow(code,d).mod(new BigInteger(n+""));
		
	}
	
	//求data的p次方
	public BigInteger pow(BigInteger data,long p){
		data = data.pow((int)p);
		return data;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		RSA rsa = new RSA();
		
		System.out.println("n的值为："+rsa.n);
       System.out.println("e的值为："+rsa.e);
       System.out.println("d的值为："+rsa.d);
       System.out.println("公钥为："+rsa.e+" "+rsa.n);
       System.out.println("私钥为："+rsa.d+" "+rsa.n);
       
       System.out.print("请输入明文：");
		
       //输入明文
       Scanner input = new Scanner(System.in);
		long m = input.nextLong();
		
		String s=m+"";
		
		BigInteger data = new BigInteger(s);
		//通过rsa调用加密方法
		BigInteger code = rsa.encode(data);
		//通过rsa调用解密方法
		BigInteger decode = rsa.decode(code);
		//BigInteger encode = rsa.encode(code);
		System.out.println("明文加密后："+code);

		System.out.println("密文解密后："+decode);
	}
  
}
